package model

import (
	"encoding/base64"
	"golang.org/x/crypto/scrypt"
	"gorm.io/gorm"
	"log"
	"next-vue-backend/utils/errmsg"
	"time"
)

type User struct {
	Username  string `gorm:"type:varchar(20); not null" json:"username" validate:"required,min=2,max=20" label:"用户名"`
	Password  string `gorm:"type:varchar(20); not null" json:"password" validate:"required,min=6,max=20" label:"密码"`
	UserId    int    `gorm:"primary_key;auto_increment" json:"user_id"`
	Avatar    string `gorm:"not null;" json:"avatar;"`
	Role      int    `gorm:"type:int" json:"role"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

// CheckUser 查询用户是否存在
func CheckUser(username string) int {
	var users User
	db.Select("user_id").Where("username = ?", username).First(&users)
	if users.UserId > 0 {
		return errmsg.ERROR_USERNAME_USED
	}
	return errmsg.SSUCCESS
}

// GetSingleUser 查询单个用户
func GetSingleUser(id int) (User, int) {
	var user User
	err = db.Where("user_id = ?", id).First(&user).Error
	if err != nil {
		return user, errmsg.ERROR
	}
	return user, errmsg.SSUCCESS
}

// CreateUser 创建用户
func CreateUser(data *User) int {
	// 密码加密
	data.Password = ScryptPw(data.Password)
	err := db.Create(&data).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// GetUsers 查询用户列表
func GetUsers(pageSize int, pageNum int) ([]User, int64) {
	var users []User
	var total int64
	err = db.Limit(pageSize).Offset((pageNum - 1) * pageSize).Find(&users).Count(&total).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return nil, 0
	}
	return users, total
}

// EditUser 编辑用户
func EditUser(id int, data *User) int {
	var user User
	var maps = make(map[string]interface{})
	maps["username"] = data.Username
	maps["role"] = data.Role
	maps["avatar"] = data.Avatar
	err = db.Model(&user).Where("user_id = ?", id).Updates(maps).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// DeleteUser 删除用户
func DeleteUser(id int) int {
	var user User
	err = db.Where("user_id = ? ", id).Delete(&user).Error
	if err != nil {
		return errmsg.ERROR
	}
	return errmsg.SSUCCESS
}

// BeforeSave BeforeSave钩子函数 密码加密
//func (u *User) BeforeSave (db2 *gorm.DB) {
//	u.Password = ScryptPw(u.Password)
//}

// ScryptPw 密码加密
func ScryptPw(password string) string {
	const KeyLen = 10
	salt := make([]byte, 8)
	salt = []byte{12, 32, 4, 6, 66, 22, 222, 11}
	HashPw, err := scrypt.Key([]byte(password), salt, 16384, 8, 1, KeyLen)
	if err != nil {
		log.Fatal(err)
	}
	fpw := base64.StdEncoding.EncodeToString(HashPw)
	return fpw
}

// CheckLogin 登录验证
func CheckLogin(username string, password string) (User, int) {
	var user User
	db.Where("username = ?", username).First(&user)

	if user.UserId == 0 {
		return user, errmsg.ERROR_USER_NOT_EXTIST
	}
	if ScryptPw(password) != user.Password {
		return user, errmsg.ERROR_PASSWORD_WRONG
	}
	if user.Role != 0 {
		return user, errmsg.ERROR_ANAUTH
	}
	return user, errmsg.SSUCCESS
}
